#include "TileManager.h"
#include "Tile.h"
#include "Game.h"
#include "SGD Wrappers\CSGD_TextureManager.h"
#include "GamePlayState.h"
#include "TutorialPlayState.h"

TileManager * TileManager::pInstance = NULL;

TileManager::TileManager(void)
{
	fileName = "";
	gameGrid = nullptr;
}


TileManager::~TileManager(void)
{
	DestroyGrid();
}


TileManager * TileManager::GetInstance()
{
	if(pInstance == NULL)
		pInstance = new TileManager();

	return pInstance;
}
void TileManager::DeleteInstance()
{
	delete pInstance;
	pInstance = nullptr;
}

void TileManager::Update(float elapsedTime)
{
	for(int x = 0; x < sizeX; x++)
	{
		for(int y = 0; y < sizeY; y++)
		{
			this->gameGrid[x][y]->Update(elapsedTime);
		}
	}
}

void TileManager::Render()
{
	CSGD_TextureManager * pTM = CSGD_TextureManager::GetInstance();

	for(int x = 0; x < sizeX; x++)
	{
		for(int y = 0; y < sizeY; y++)
		{
			this->gameGrid[x][y]->Render();
		}
	}

}

void TileManager::CreateGrid(std::string file)
{
	this->fileName = file;

	TiXmlDocument doc;
	
	if(!doc.LoadFile(this->fileName.c_str()))
		return;

	TiXmlElement * root = doc.RootElement();
	if(root == nullptr)
		return;

	TiXmlElement * tileManager = root->FirstChildElement("tm");

	tileManager->Attribute("sizeX",&this->sizeX);
	tileManager->Attribute("sizeY",&this->sizeY);
	tileManager->Attribute("tileSizeX",&this->tileSizeX);
	tileManager->Attribute("tileSizeY",&this->tileSizeY);
	tileManager->Attribute("posX",&this->posX);
	tileManager->Attribute("posY",&this->posY);
	tileManager->Attribute("numRows",&this->bmpCellHeight);
	tileManager->Attribute("numCols",&this->bmpCellWidth);
	
	const char * temp = tileManager->GetText();

	this->tileSetBmpFile = "resource\\";
	this->tileSetBmpFile += temp;

	double d;
	tileManager->Attribute("scale",&d);
	this->scale = float(d);

	this->gameGrid = new Tile**[sizeX];

	for(int i = 0; i < sizeX;i++)
	{
		gameGrid[i] = new Tile*[sizeY];
	}


	TiXmlElement * tile = root->FirstChildElement("tile");

	while(tile !=nullptr)
	{
		Tile * newTile = new Tile();

		int intBuffer;

		tile->Attribute("terrainType",&intBuffer);
		newTile->SetTerrainType(intBuffer);

		tile->Attribute("xPos",&intBuffer);
		newTile->SetX(intBuffer);

		tile->Attribute("yPos",&intBuffer);
		newTile->SetY(intBuffer);

		tile->Attribute("imageID",&intBuffer);
		newTile->SetImageID(intBuffer);

		tile->Attribute("obstacle",&intBuffer);
		bool obstacle;
		if(intBuffer == 1)
			obstacle = true;
		else
			obstacle = false;
		newTile->SetObstacle(obstacle);

		newTile->SetCharacter(nullptr);

		const char * cBuffer = tile->GetText();

		if(cBuffer != nullptr)
			newTile->SetEventString(cBuffer);

		gameGrid[newTile->GetX()][newTile->GetY()] = newTile;

		tile = tile->NextSiblingElement("tile");

	}


}

void TileManager::DestroyGrid()
{
	if(pInstance == NULL)
		return;

	if(gameGrid != nullptr)
	{
		for(int x = 0; x < this->sizeX;x++)
		{
			for(int y = 0; y < this->sizeY;y++)
			{
				gameGrid[x][y]->SetCharacter(nullptr);
				delete gameGrid[x][y];
			}
		}

		for(int i = 0; i < sizeX; i++)
			delete[] gameGrid[i];

		delete[] gameGrid;
		gameGrid = nullptr;
	}

	
}

RECT TileManager::CreateTileSourceRect(int cellID)
{
	int col = 0;
	int row = 0;

	for(int i = 0; i < cellID;i++)
	{
		col++;
		if(col >= this->bmpCellWidth)
		{
			col = 0;
			row++;
			if(row >= this->bmpCellHeight)
			{
				col = 0;
				row = 0;
			}
		}
	}

	RECT r;
	r.left = col * this->tileSizeX;
	r.right = r.left + this->tileSizeX;
	r.top = row * this->tileSizeY;
	r.bottom = r.top + this->tileSizeY;

	return r;
}

Tile * TileManager::ReturnHilightedTile(int stateType)
{
	/*int screenX = Game::GetInstance()->GetWinWidth()/2;
	int screenY = Game::GetInstance()->GetWinHeight()/2;

	int x = (int)(((screenX - (posX*scale))/(this->tileSizeX*scale)));
	int y = (int)(((screenY - (posY*scale))/(this->tileSizeY*scale)));

	if(x >= 0 && x <= this->sizeX && y >= 0 && y <= sizeY)
		return this->gameGrid[x][y];
	else
		return nullptr;*/
	GamePlayState * gps;
	TutorialPlayState* tps;

	

	if(stateType == 0)
	{
	 gps = GamePlayState::GetInstance();
	 return this->gameGrid[gps->GetCursorX()][gps->GetCursorY()];
	}

	else
	{
		tps = TutorialPlayState::GetInstance();
		return this->gameGrid[tps->GetCursorX()][tps->GetCursorY()];
	}

	

}


void TileManager::ResetHighlights()
{
	for(int x = 0; x < this->GetSizeX();x++)
	{
		for(int y = 0 ; y < this->GetSizeY();y++)
		{
			this->gameGrid[x][y]->HighlightTile(false);
		}
	}
}

